package com.ghy.ic.mo.controller;

import com.ghy.ic.mo.dao.*;
import com.ghy.ic.mo.domain.bo.User;
import com.ghy.ic.mo.domain.vo.BookInfoVo;
import com.ghy.ic.mo.domain.vo.OutResult;
import com.ghy.ic.mo.domain.vo.UserBookBaseInfoAndStatusVo;
import com.ghy.ic.mo.utils.JodaTimeUtil;
import com.google.common.collect.Lists;
import com.jfinal.core.Controller;
import org.apache.log4j.Logger;

import java.util.List;

import static com.ghy.ic.mo.constant.BcsConstant.*;

/**
 * 普通用户的接口实现，与User.class没有直接关系，只是刚好命名相似而已
 * @author Y-Tree
 * @date 18-12-1 下午10:50
 */
public class UserController extends Controller {

    private static final Logger LOGGER =Logger.getLogger(UserController.class);

    private static final String BOOK_RESULT = "bookResult";
    private static final String BOOK_FAIL = "预约失败!";
    private static final String BOOK_SUCCESS = "预约成功！";
    private static final String CANCEL_FAIL = "取消失败！";
    private static final String CANCEL_SUCCESS = "取消成功！";
    private static final String UPDATE_FAIL = "更新失败！";
    private static final String UPDATE_SUCCESS = "更新成功！";
    private static final String EVALUATION_FAIL = "评价失败！";
    private static final String EVALUATION_SUCCESS = "评价成功！";
    private static final String GET_BOOK_USER_LIST_FAIL = "获取预约用户列表失败！";
    private static final String GET_BOOK_USER_LIST_SUCCESS = "获取预约用户列表成功！";
    private static final String PRINCIPAL_IS_NOT = "没有被代理人的记录。";
    private static final String GET_EVALUATION_INFO_FAIL = "获取评价失败！";
    private static final String GET_EVALUATION_INFO_SUCCESS = "获取评价成功！";
    private static final String BOOK_USER_FULL = "预约人数已达上限！";
    private static final String GET_SESSION_USER_IS_NULL = "获取session中的用户为null！";

    private static final String PARA_USER_NAME = "userName";
    private static final String PARA_USER_TEL = "userTel";
    private static final String PARA_REMARK = "remark";
    private static final String PARA_AGENT_FLAG = "agentFlag";
    private static final String PARA_VEHICLE_DELIVERY_ID = "vehicleDeliveryId";
    private static final String PARA_BOOK_ID = "bookId";
    private static final String PARA_SERVICE_ATTITUDE = "serviceAttitude";
    private static final String PARA_DRIVER_SKILL = "driverSkill";
    private static final String PARA_OVERALL_FEEL = "overallFeel";
    private static final String PARA_EVALUATION_MESSAGE = "evaluationMessage";
    private static final String PARA_DRIVER_ID = "driverId";

    /**
     * 添加用户提交的预约信息
     */
    public void add(){

        // 1. 获取用户提交预约信息
        String userName = getPara(PARA_USER_NAME);
        String userTelephone = getPara(PARA_USER_TEL);
        String remark = getPara(PARA_REMARK);
        int agentFlag = getParaToInt(PARA_AGENT_FLAG);
        int vDId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);

        LOGGER.info("add user name : " + userName);
        LOGGER.info("add user tel : " + userTelephone);
        LOGGER.info("add remark : " + remark);
        LOGGER.info("add agent flag : " + agentFlag);
        LOGGER.info("add vehicle delivery id  : " + vDId);

        // 2. 判断预约人数是否到达上限
        BcsVehicleDeliveryInfo vehicleDeliveryInfo = BcsVehicleDeliveryInfo.getInfoById(vDId);
        Integer maxNum = vehicleDeliveryInfo.getMaxNum();
        if (maxNum != 0){
            // 表明有人数限制

            int currentUserCount = vehicleDeliveryInfo.getBookNum() + 1;
            if (currentUserCount > maxNum){
                // 表明预约人数已达上限
                LOGGER.error(BOOK_USER_FULL);
                setAttr(BOOK_RESULT, new OutResult().resultMap(2, "err", BOOK_USER_FULL));
                renderJson(BOOK_RESULT, new OutResult().resultMap(2, "err", BOOK_USER_FULL));
                return;
            }
        }

        // 3. 将信息保存至数据库中
        User user = getSessionAttr("user");
        String userId = user.getUserid();
        String agentName = user.getName();

        BcsUserBookCarInfo bookInfoPo = new BcsUserBookCarInfo();
        if (agentFlag == 0){
            // 该用户要去代理其他用户进行报名
            bookInfoPo.setAgent(agentName);
            bookInfoPo.setUserName(userName);
            // 根据用户名和电话查询被代理的用户id, Principal 委托人，在这里的意思是指被代理报名的人 委托人，在这里的意思是指被代理报名的人
            String principalId = MmsRyxx.getUserIdByPhoneAndUserName(userTelephone, userName);
            bookInfoPo.setUserId(principalId);
        }else {
            bookInfoPo.setUserId(userId);
            bookInfoPo.setUserName(agentName);
        }
        bookInfoPo.setVehicleDeliveryId(vDId);
        bookInfoPo.setUserTelephone(userTelephone);
        bookInfoPo.setUserRemarks(remark);

        // 4. 更新库中预约人数
        int currentBookUserCpunt = vehicleDeliveryInfo.getBookNum() + 1;

        BcsVehicleDeliveryInfo.updateByBookNum(vDId, currentBookUserCpunt);
        returnResult(BcsUserBookCarInfo.add(bookInfoPo), userName, BOOK_FAIL, BOOK_SUCCESS);
    }

    /**
     * 用户更新提交的预约信息
     */
    public void update(){

        // 1. 获取用户提交预约信息
        String userName = getPara(PARA_USER_NAME);
        String userTelephone = getPara(PARA_USER_TEL);
        String remark = getPara(PARA_REMARK);
        int agentFlag = getParaToInt(PARA_AGENT_FLAG);
        int vDId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);
        int bookId = getParaToInt(PARA_BOOK_ID);

        LOGGER.info("update user name : " + userName);
        LOGGER.info("update user tel : " + userTelephone);
        LOGGER.info("update remark : " + remark);
        LOGGER.info("update agent flag : " + agentFlag);
        LOGGER.info("update vehicle delivery id  : " + vDId);
        LOGGER.info("update book id : " + bookId);

        BcsUserBookCarInfo bookInfoPo = new BcsUserBookCarInfo();
        bookInfoPo.setId(bookId);
        bookInfoPo.setUserName(userName);
        bookInfoPo.setUserTelephone(userTelephone);
        bookInfoPo.setUserRemarks(remark);

        // 更新自己获取被代理人的信息
        returnResult(BcsUserBookCarInfo.updateAll(bookInfoPo), userName,
                UPDATE_FAIL, UPDATE_SUCCESS);
    }

    /**
     * 用户取消预约
     * 取消操作会一并将被代理人预约一块取消
     */
    public void cancel(){

        String userName = getPara(PARA_USER_NAME);
        int vdId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);
        int bookId = getParaToInt(PARA_BOOK_ID);

        // 1. 根据用户名和班车班次查找被代理的用户, Principal 委托人，在这里的意思是指被代理报名的人
        BcsUserBookCarInfo principal = BcsUserBookCarInfo.getPrincipalByAgentNameAndVdId(userName, vdId);

        // 2. 取消该用户和被代理的用户的班车预约
        boolean userDelFlag = BcsUserBookCarInfo.delete(bookId);
        boolean principalDelFlag;
        if (principal == null){
            principalDelFlag = true;
        }else {
            principalDelFlag = BcsUserBookCarInfo.delete(principal.getId());
        }

        if (!(userDelFlag && principalDelFlag)){
            LOGGER.error(CANCEL_FAIL);
            setAttr(BOOK_RESULT, new OutResult().resultMap(1, "err", CANCEL_FAIL));
            renderJson(BOOK_RESULT, new OutResult().resultMap(1, "err", CANCEL_FAIL));
        }else {

            // 更新预约人数
            int currentBookUserCount = BcsVehicleDeliveryInfo.getInfoById(vdId).getBookNum() - 1;
            BcsVehicleDeliveryInfo.updateByBookNum(vdId, currentBookUserCount);

            LOGGER.info(CANCEL_SUCCESS);
            setAttr(BOOK_RESULT, new OutResult().resultMap(0, "ok", CANCEL_SUCCESS));
            renderJson(BOOK_RESULT, new OutResult().resultMap(0, "ok", CANCEL_SUCCESS));
        }
    }

    /**
     * 获取被该用户所代理的用户信息
     */
    public void getBaseInfo(){
        // do something
        int bookId = getParaToInt(PARA_BOOK_ID);
        int agentFlag = getParaToInt(PARA_AGENT_FLAG);

        BcsUserBookCarInfo result = null;

        // 1. 根据bookId获取该用户信息
        BcsUserBookCarInfo userInfo = BcsUserBookCarInfo.getUserInfoById(bookId);

        if (agentFlag == 1){

            result = userInfo;
        }else if (agentFlag == 0){

            // 2. 根据代理人名称车辆派送id获取被代理人信息 agentFlag == 0, 表明要获取被代理人信息, Principal 委托人，在这里的意思是指被代理报名的人
            result = BcsUserBookCarInfo.getPrincipalByAgentNameAndVdId(
                    userInfo.getUserName(), userInfo.getVehicleDeliveryId());
        }else {
            // nothing
            LOGGER.info("agentFlag : " + agentFlag);
        }

        if (result != null){

            LOGGER.info("获取被代理人信息成功。");
            setAttr(BOOK_RESULT, new OutResult().resultMap(0, "ok", result));
            renderJson(BOOK_RESULT, new OutResult().resultMap(0, "ok", result));
        }else {
            LOGGER.info(PRINCIPAL_IS_NOT);
            setAttr(BOOK_RESULT, new OutResult().resultMap(2, "null", PRINCIPAL_IS_NOT));
            renderJson(BOOK_RESULT, new OutResult().resultMap(2, "null", PRINCIPAL_IS_NOT));
        }
    }

    /**
     * 获取预约车辆的用户列表
     */
    public void getBookUserList(){

        int vDId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);

        // 1. 获取已预约的用户列表
        List<BcsUserBookCarInfo> bookUserList
                = BcsUserBookCarInfo.getBcsUserBookCarInfosByVehicleDeliveryId(vDId);

        if (bookUserList.isEmpty()){
            // 预约用户列表为空
            LOGGER.error(GET_BOOK_USER_LIST_FAIL);
            setAttr(BOOK_RESULT, new OutResult().resultMap(1, "err", GET_BOOK_USER_LIST_FAIL));
            renderJson(BOOK_RESULT, new OutResult().resultMap(1, "err", GET_BOOK_USER_LIST_FAIL));
        }else {
            // 存在预约用户
            // 2. 封装用户信息
            List<BookInfoVo> bookUserVoList = Lists.newArrayList();
            for (BcsUserBookCarInfo bookUserInfo : bookUserList){

                BookInfoVo bookInfoVo = new BookInfoVo();
                bookInfoVo.setId(bookUserInfo.getId());
                if (bookUserInfo.getAgent() == null){
                    bookInfoVo.setAgent("空");
                }else {
                    bookInfoVo.setAgent(bookUserInfo.getAgent());
                }
                bookInfoVo.setUserId(bookUserInfo.getUserId());
                bookInfoVo.setUserName(bookUserInfo.getUserName());
                bookInfoVo.setUserTelephone(bookUserInfo.getUserTelephone());
                String avatar = MmsRyxx.getUserInfoByUserId(bookUserInfo.getUserId()).getAvatar();
                if (avatar == null){
                    bookInfoVo.setAvatar("kong");
                }else {
                    bookInfoVo.setAvatar(avatar);
                }
                bookInfoVo.setVehicleDeliveryId(bookUserInfo.getVehicleDeliveryId());
                bookInfoVo.setCreateTime(JodaTimeUtil.date2String(bookUserInfo.getCreateTime()));
                bookUserVoList.add(bookInfoVo);
            }
            LOGGER.info(GET_BOOK_USER_LIST_SUCCESS);
            setAttr(BOOK_RESULT, new OutResult().resultMap(0, "ok", bookUserVoList));
            renderJson(BOOK_RESULT, new OutResult().resultMap(0, "ok", bookUserVoList));
        }

    }

    /**
     * 根据userId获取用户信息即一些操作状态
     */
    public void getUserBaseInfo(){

        int vDId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);

        User user = getSessionAttr("user");
        String userId = user.getUserid();
        String userName = user.getName();
        String userTelephone = user.getMobile();
//        String userId = "huty";
//        String userName = "胡腾云";
//        String userTelephone = "15101597780";

        UserBookBaseInfoAndStatusVo infoAndStatus = new UserBookBaseInfoAndStatusVo();

        infoAndStatus.setUserId(userId);
        infoAndStatus.setUserName(userName);
        infoAndStatus.setUserTelephone(userTelephone);
        infoAndStatus.setVehicleDeliveryId(vDId);

        // 管理员权限校验
        URole userRoleInfo = URole.getUserRoleInfo(MODULES, userId);
        if (userRoleInfo == null){
            LOGGER.info("用户："+ userName +" 不是管理员。");
            infoAndStatus.setIsAdmin(IS_NOT_ADMIN);
        }else {
            LOGGER.info("用户："+ userName +" 是管理员。");
            infoAndStatus.setIsAdmin(IS_ADMIN);
        }

        // 是否预约
        BcsUserBookCarInfo bookInfo
                = BcsUserBookCarInfo.getUserBookInfoByVehicleDeliveryIdAndUserId(vDId, userId);
        if (bookInfo == null){
            LOGGER.info("用户："+ userName +" 还没有预约。");
            infoAndStatus.setIsBook(IS_NOT_BOOK);
            infoAndStatus.setBookId(NOT_BOOK_ID);

        }else {
            LOGGER.info("用户："+ userName +" 已预约。");
            infoAndStatus.setIsBook(IS_BOOK);
            infoAndStatus.setBookId(bookInfo.getId());
            infoAndStatus.setUserRemark(bookInfo.getUserRemarks());
        }

        // 是否评价
        List<BcsDriverServiceEvaluation> evaluationInfoList
                = BcsDriverServiceEvaluation.getEvaluationInfoByVehicleDeliveryIdAndUserId(vDId, userId);
        if (BcsVehicleDeliveryInfo.getInfoById(vDId).getDriverId() != null){
            int driverCount = BcsVehicleDeliveryInfo.getInfoById(vDId).getDriverId().split(",").length;

            if (evaluationInfoList.size() != driverCount){
                LOGGER.info("用户："+ userName +" 还没有完全评价。");
                infoAndStatus.setIsEvaluation(IS_NOT_EVALUATION);
            }else {
                LOGGER.info("用户："+ userName +" 已评价。");
                infoAndStatus.setIsEvaluation(IS_EVALUATION);
            }
        }else {
            LOGGER.info("用户："+ userName +" 一个也没有评价。");
            infoAndStatus.setIsEvaluation(IS_NOT_EVALUATION);
        }


        setAttr(BOOK_RESULT, new OutResult().resultMap(0, "ok", infoAndStatus));
        renderJson(BOOK_RESULT, new OutResult().resultMap(0, "ok", infoAndStatus));

    }

    /**
     * 用户对司机服务的评价
     */
    public void serviceEvaluation(){

        int vDId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);
        BcsDriverServiceEvaluation serviceEvaluation = new BcsDriverServiceEvaluation();

        // 1. 获取用户对司机的服务评价值
        String sericeAttitude = getPara(PARA_SERVICE_ATTITUDE);
        String driverSkill = getPara(PARA_DRIVER_SKILL);
        String overallFeel = getPara(PARA_OVERALL_FEEL);
        String evaluationMessage = getPara(PARA_EVALUATION_MESSAGE);
        int driverId = getParaToInt(PARA_DRIVER_ID);

        // 2. 获取评价人和司机信息
        User user = getSessionAttr("user");
        String userId = user.getUserid();
        String userName = user.getName();

        // 3. 将本次评价存入数据库
        serviceEvaluation.setDServiceAttitude(sericeAttitude);
        serviceEvaluation.setDDrivingSkill(driverSkill);
        serviceEvaluation.setDOverallFeel(overallFeel);
        serviceEvaluation.setUEvaluator(userId);
        serviceEvaluation.setDriverId(driverId);
        serviceEvaluation.setVehicleDeliveryId(vDId);
        serviceEvaluation.setEvaluationMessage(evaluationMessage);

        returnResult(BcsDriverServiceEvaluation.add(serviceEvaluation), userName, EVALUATION_FAIL, EVALUATION_SUCCESS);
    }

    /**
     * 根据vDId和用户id获取评价信息
     */
    public void getServiceEvaluationInfo(){

        int vDId = getParaToInt(PARA_VEHICLE_DELIVERY_ID);
        int driverId = getParaToInt(PARA_DRIVER_ID);

        User user = getSessionAttr("user");
        String userId = user.getUserid();
        String userName = user.getName();

        BcsDriverServiceEvaluation info
                = BcsDriverServiceEvaluation.getEvaluationInfoByVehicleDeliveryIdAndUserIdAndDriverId(vDId, userId, driverId);
        if (info == null){
            LOGGER.error("用户： " + userName + GET_EVALUATION_INFO_FAIL);
            setAttr(BOOK_RESULT, new OutResult().resultMap(1, "err", GET_EVALUATION_INFO_FAIL));
            renderJson(BOOK_RESULT, new OutResult().resultMap(1, "err", GET_EVALUATION_INFO_FAIL));
        }else {
            LOGGER.info("用户： " + userName + GET_EVALUATION_INFO_SUCCESS);
            setAttr(BOOK_RESULT, new OutResult().resultMap(0, "ok", info));
            renderJson(BOOK_RESULT, new OutResult().resultMap(0, "ok", info));
        }
    }

    /**
     * 判断用户信息是否为空
     */
    public void isUserInfoNull(){

        User user = getSessionAttr("user");
        if (user == null){
            String redirectUrl = JbModuleQyCodeUrl.getRedirectUrlByModule(MODULES);
            LOGGER.error(GET_SESSION_USER_IS_NULL);
            setAttr(BOOK_RESULT, new OutResult().resultMap(1, "err", redirectUrl));
            renderJson(BOOK_RESULT, new OutResult().resultMap(1, "err", redirectUrl));
        }
    }

    /**
     *
     * @param status 操作数据库状态
     * @param userName 用户名
     * @param failMes 失败信息
     * @param successMes 成功信息
     */
    private void returnResult(boolean status, String userName, String failMes, String successMes){

        if (!status) {

            LOGGER.error("用户： " + userName + failMes);
            setAttr(BOOK_RESULT, new OutResult().resultMap(1, "err", failMes));
            renderJson(BOOK_RESULT, new OutResult().resultMap(1, "err", failMes));
        } else {

            LOGGER.info("用户： " + userName + successMes);
            setAttr(BOOK_RESULT, new OutResult().resultMap(0, "ok", successMes));
            renderJson(BOOK_RESULT, new OutResult().resultMap(0, "ok", successMes));
        }
    }

}
